// ==========================
// InsertPosition
// ==========================
var MIN_SLOT = 6;
var MAX_SLOT = 768;
var MAX_REPEAT = 4;

function clip(v, min, max) {
    return v < min ? min : v > max ? max : v;
}

function CellRandom() {
    this.mOthers = false;
    this.mMax = 0;
    this.mBaseLn = 0;
    this.mTotal = 0;
    this.mRepeat = 0;
    this.mLast = 0;

    this.mAdjust = [10, 10, 10];
}
CellRandom.prototype.gen123 = function (r, range) {
    var total = 0;
    for (var i = 0; i < 3; i++) {
        total += this.mAdjust[i];
    }

    r = r * total / range;
    var result = 0;
    for (var i = 0; i < 3; i++) {
        if (r < this.mAdjust[i]) {
            result = i;
            break;
        }
        r -= this.mAdjust[i];
    }

    for (var i = 0; i < 3; i++) {
        if (result == i) {
            this.mAdjust[i] = clip(this.mAdjust[i] - 4, 2, 10);
        } else {
            this.mAdjust[i] = clip(this.mAdjust[i] + 2, 0, 10);
        }
    }

    return result + 1;
};
CellRandom.prototype.updateMax = function (count) {
    count = count / 8;
    if (count < MIN_SLOT) {
        this.mTotal = 0;
        this.mOthers = false;
        return;
    } else {
        this.mOthers = true;
    }
    if (count > MAX_SLOT) {
        count = MAX_SLOT;
    }
    var start = 6;
    var startln = this.mBaseLn = Math.log(count) * 0.5;
    this.mTotal = this.mBaseLn;
    while (start < count) {
        startln = startln / 2;
        this.mTotal += startln;
        start *= 2;
    }
    this.mMax = start;
};
CellRandom.prototype.randomCell = function () {
    var r = Math.random() * 100;
    var remain = 100;

    if (this.mOthers) {
        var start = MIN_SLOT;
        var startln = this.mBaseLn;
        if (r < startln) {
            return start;
        }

        var totalln = this.mBaseLn;
        while (start < this.mMax) {
            start *= 2;
            startln /= 2;
            totalln += startln;
            if (r < totalln) {
                return start;
            }
        }

        remain -= totalln;
        r -= totalln;
    }

    var count = this.gen123(r, remain);

    if (this.mLast == count) {
        if (++this.mRepeat > MAX_REPEAT) {
            this.mAdjust[count - 1]--;
            count = (count + 3) % 3 + 1;
            this.mRepeat = 1;
        }
    } else {
        this.mRepeat = 1;
    }

    this.mLast = count;
    return count;
};

module.exports = CellRandom;